package com.yanqu.road.server.gameplayer.module.player;

import com.yanqu.road.entity.config.battle.BattleResult;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eTradeWarBattleType;
import com.yanqu.road.entity.log.LogTradeWarBattle;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.player.UserPatronsSimple;
import com.yanqu.road.entity.tradewar.*;
import com.yanqu.road.logic.bussiness.tradewar.TradeWarTeamBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.TradeWarTeamPb;
import com.yanqu.road.pb.tradewar.team.TradeWarTeamProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.logic.battle.BattleManager;
import com.yanqu.road.server.manger.VipMgr;
import com.yanqu.road.server.manger.config.TradeWarConfigMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.patrons.PatronsSimpleCacheMgr;
import com.yanqu.road.server.manger.player.TradeWarMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class TradeWarTeamModule extends GeneralModule {

    private UserTradeWarTeam userTradeWarTeam;
    private UserCrossTradeWarTeam userCrossTradeWarTeam;

    public TradeWarTeamModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        userTradeWarTeam = TradeWarTeamBussiness.getUserTradeWarTeam(player.getUserId());
        initTradeWarTeam();

        userCrossTradeWarTeam = TradeWarTeamBussiness.getUserCrossTradeWarTeam(player.getUserId());
        initCrossTradeWarTeam();
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (null != userTradeWarTeam) {
            if (userTradeWarTeam.isInsertOption()) {
                TradeWarTeamBussiness.addUserTradeWarTeam(userTradeWarTeam);
            } else if (userTradeWarTeam.isUpdateOption()) {
                TradeWarTeamBussiness.updateUserTradeWarTeam(userTradeWarTeam);
            }
        }
        if (null != userCrossTradeWarTeam) {
            if (userCrossTradeWarTeam.isInsertOption()) {
                TradeWarTeamBussiness.addUserCrossTradeWarTeam(userCrossTradeWarTeam);
            } else if (userCrossTradeWarTeam.isUpdateOption()) {
                TradeWarTeamBussiness.updateUserCrossTradeWarTeam(userCrossTradeWarTeam);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        syncTradeWarTeam();
    }

    /**
     * 初始化队伍数据
     */
    public void initTradeWarTeam() {
        if (null == userTradeWarTeam) {
            UserTradeWarTeam tradeWarTeam = new UserTradeWarTeam();
            tradeWarTeam.setUserId(player.getUserId());
            tradeWarTeam.setPatronsTeamListString("");
            tradeWarTeam.setBuyBuffTimesListString("");
            tradeWarTeam.setInsertOption();
            userTradeWarTeam = tradeWarTeam;
        }
    }

    private void initCrossTradeWarTeam() {
        if (null == userCrossTradeWarTeam) {
            UserCrossTradeWarTeam crossTradeWarTeam = new UserCrossTradeWarTeam();
            crossTradeWarTeam.setUserId(player.getUserId());
            crossTradeWarTeam.setPatronsTeamListString("");
            crossTradeWarTeam.setBuyBuffTimesListString("");
            crossTradeWarTeam.setInsertOption();
            userCrossTradeWarTeam = crossTradeWarTeam;
        }
    }

    /**
     * 同步队伍数据
     */
    public void syncTradeWarTeam() {
        TradeWarTeamProto.TradeWarTeamMsg.Builder msg = TradeWarTeamPb.parseTradeWarTeamMsg(userTradeWarTeam, userCrossTradeWarTeam);
        if (null != msg) {
            player.sendPacket(Protocol.U_TRADE_WAR_TEAM_SYNC, msg);
        }
    }

    public int titleOrVipCheck(int teamType) {
        if (teamType == 0) {
            if (player.getTitleId() < GameConfig.TRADE_WAR_TEAM_OPEN_LEVEL &&
                    VipMgr.getVipLv(player.getUserInfo().getVipExp()) < GameConfig.TRADE_WAR_TEAM_OPEN_VIP) {
                if (player.getTitleId() < GameConfig.TRADE_WAR_TEAM_OPEN_LEVEL) {
                    return GameErrorCode.E_TITLE_LEVEL_NO_ENOUGH;
                } else {
                    return GameErrorCode.E_VIP_LEVEL_NO_ENOUGH;
                }
            }
        } else {
            if (player.getTitleId() < GameConfig.CROSS_TRADE_WAR_TEAM_OPEN_LEVEL &&
                    VipMgr.getVipLv(player.getUserInfo().getVipExp()) < GameConfig.CROSS_TRADE_WAR_TEAM_OPEN_VIP) {
                if (player.getTitleId() < GameConfig.CROSS_TRADE_WAR_TEAM_OPEN_LEVEL) {
                    return GameErrorCode.E_TITLE_LEVEL_NO_ENOUGH;
                } else {
                    return GameErrorCode.E_VIP_LEVEL_NO_ENOUGH;
                }
            }
        }
        return 0;
    }

    /**
     * 增加队伍
     *
     * @param patronsIdList
     * @param teamType
     * @return
     */
    public int addTradeWarTeam(List<Integer> patronsIdList, int teamType) {
        int result = titleOrVipCheck(teamType);
        if (0 != result) {
            return result;
        }
        if (teamType == 0) {
            if (null == userTradeWarTeam) {//系统未解锁
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
            if (patronsIdList.size() == 0 || patronsIdList.size() > GameConfig.TRADE_WAR_MAX_BATTLE_PATRONS_COUNT) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_COUNT_ERROR;
            }
            if (getTeamCount() >= GameConfig.TRADE_WAR_TEAM_MAX_COUNT) {
                return GameErrorCode.E_TRADE_WAR_TEAM_COUNT_MAX;
            }
            if (!player.getModule(PatronsModule.class).checkPatronsList(patronsIdList)) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_ERROR;
            }
            if (checkPatronsRepeat(-1, patronsIdList, teamType)) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_HAS_REPEAT;
            }
            userTradeWarTeam.addPatronsTeam(patronsIdList);
        } else {
            if (null == userCrossTradeWarTeam) {//系统未解锁
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
            if (patronsIdList.size() == 0 || patronsIdList.size() > GameConfig.TRADE_WAR_MAX_BATTLE_PATRONS_COUNT) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_COUNT_ERROR;
            }
            if (getCrossTeamCount() >= GameConfig.CROSS_TRADE_WAR_TEAM_MAX_COUNT) {
                return GameErrorCode.E_TRADE_WAR_TEAM_COUNT_MAX;
            }
            if (!player.getModule(PatronsModule.class).checkPatronsList(patronsIdList)) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_ERROR;
            }
            if (checkPatronsRepeat(-1, patronsIdList, teamType)) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_HAS_REPEAT;
            }
            userCrossTradeWarTeam.addPatronsTeam(patronsIdList);
        }

        return 0;
    }

    /**
     * 变更队伍
     *
     * @param index
     * @param patronsIdList
     * @param teamType
     * @return
     */
    public int editTradeWarTeam(int index, List<Integer> patronsIdList, int teamType) {
        int result = titleOrVipCheck(teamType);
        if (0 != result) {
            return result;
        }
        if (teamType == 0) {
            if (null == userTradeWarTeam) {//系统未解锁
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
            if (patronsIdList.size() == 0 || patronsIdList.size() > GameConfig.TRADE_WAR_MAX_BATTLE_PATRONS_COUNT) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_COUNT_ERROR;
            }
            if (!player.getModule(PatronsModule.class).checkPatronsList(patronsIdList)) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_ERROR;
            }
            if (checkPatronsRepeat(index, patronsIdList, teamType)) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_HAS_REPEAT;
            }
            userTradeWarTeam.changePatronsTeam(index, patronsIdList);
        } else {
            if (null == userCrossTradeWarTeam) {//系统未解锁
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
            if (patronsIdList.size() == 0 || patronsIdList.size() > GameConfig.TRADE_WAR_MAX_BATTLE_PATRONS_COUNT) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_COUNT_ERROR;
            }
            if (!player.getModule(PatronsModule.class).checkPatronsList(patronsIdList)) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_ERROR;
            }
            if (checkPatronsRepeat(index, patronsIdList, teamType)) {
                return GameErrorCode.E_TRADE_WAR_TEAM_PATRONS_HAS_REPEAT;
            }
            userCrossTradeWarTeam.changePatronsTeam(index, patronsIdList);
        }

        return 0;
    }

    /**
     * 移除队伍
     *
     * @param index
     * @param teamType
     * @return
     */
    public int removeTradeWarTeam(int index, int teamType){
        int result = titleOrVipCheck(teamType);
        if(0 != result){
            return result;
        }
        if (teamType == 0){
            if(null == userTradeWarTeam){//系统未解锁
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
            if(index < 0 || index >= userTradeWarTeam.getPatronsTeamList().size()){
                return GameErrorCode.E_TRADE_WAR_TEAM_REMOVE_TEAM_NO_EXIST;
            }
            userTradeWarTeam.removePatronsTeam(index);
            userTradeWarTeam.removeBuyBuffTimes(index);
        }else{
            if(null == userCrossTradeWarTeam){//系统未解锁
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
            if(index < 0 || index >= userCrossTradeWarTeam.getPatronsTeamList().size()){
                return GameErrorCode.E_TRADE_WAR_TEAM_REMOVE_TEAM_NO_EXIST;
            }
            userCrossTradeWarTeam.removePatronsTeam(index);
            userCrossTradeWarTeam.removeBuyBuffTimes(index);
        }

        return 0;
    }

    /**
     * 出战
     * @return
     */
    public List<BattleResult> tradeWarTeamBattle(){
        List<BattleResult> resultList = new ArrayList<>();
        TradeWarModule tradeWarModule = player.getModule(TradeWarModule.class);
        UserTradeWarInfo userTradeWarInfo = tradeWarModule.getUserTradeWarInfo();
        long oldScore;
        long totalPreTime = System.currentTimeMillis();
        long preTime;
        tradeWarModule.calcRandomBattleTimes();
        LinkedList<TradeWarTeamSortEntity> sortList = getSortTeamList(userTradeWarTeam.getPatronsTeamList());
        for(TradeWarTeamSortEntity data : sortList){
            ReduceTeamRandomBattleTimesResult reduceResult = tradeWarModule.reduceTeamRandomBattleTimes(data.getPatronsIdList());
            if(reduceResult.getBattleTimes() <= 0){
                log.info("trade war fast battle team patrons all no times,team patrons list:{}", data.getPatronsIdList());
                continue;
            }
            preTime = System.currentTimeMillis();
            //获取随机对手
            UserTradeWarInfo enemyTradeWarInfo = TradeWarMgr.findRandomEnemy(player.getUserId());
            if(null == enemyTradeWarInfo){
                log.info("trade war fast battle no find enemy,team patrons list:{}", reduceResult.getPatronsList());
                continue;
            }
            //战斗
            List<UserPatronsSimple> enemyPatronsSimpleList = PatronsSimpleCacheMgr.getUserPatronsSimpleList(enemyTradeWarInfo.getUserId());
            if(null == enemyPatronsSimpleList){
                log.info("trade war fast battle no find enemy patrons,team patrons list:{}", reduceResult.getPatronsList());
                continue;
            }
            log.info("trade war fast battle find enemy cost:{},teamIndex:{}", System.currentTimeMillis() - preTime, data.getTeamIndex());
            preTime = System.currentTimeMillis();

            List<UserPatrons> patronsList = player.getModule(PatronsModule.class).getUserPatronsList(reduceResult.getPatronsList());
            List<UserPatrons> enemyPatronsList = PatronsSimpleCacheMgr.parseUserPatronsList(enemyPatronsSimpleList);
            //打乱对面人才
            enemyPatronsList = TradeWarConfigMgr.disorganizeOrder(enemyPatronsList);
            //计算鼓舞
            int defineBuyBuffTimes = TradeWarConfigMgr.getTeamBuyBuffTimes(userTradeWarTeam.getBuyBuffTimes(data.getTeamIndex()));
            int buyBuffTimes = teamBuyBuffTimes(defineBuyBuffTimes, reduceResult.getBattleTimes());
            int buffAddition = TradeWarConfigMgr.getTradeWarBuffAddition(buyBuffTimes);

            log.info("trade war fast battle buy buff time:{}, cost:{},teamIndex:{}", buyBuffTimes, System.currentTimeMillis() - preTime, data.getTeamIndex());
            preTime = System.currentTimeMillis();
            //战斗
            BattleResult battleResult = BattleManager.battle(player.getUserId(), patronsList, enemyTradeWarInfo.getUserId(),
                    enemyPatronsList, buffAddition, true, false);

            TradeWarMgr.dealBattleResult(battleResult, eTradeWarBattleType.RandomBattle.getValue(), 0,
                    reduceResult.getBattleTimes(), "");
            battleResult.setTeamIndex(data.getTeamIndex());

            //结果奖励
            oldScore = userTradeWarInfo.getScore();
            tradeWarModule.changeScore(battleResult);
            // 增加公告信息
            if (battleResult.getKillPatronsCount() >= GameConfig.TRADE_WAR_NOTICE_NEED_KILL_PATRONS_COUNT) {
                tradeWarModule.addNotice(battleResult);
            }
            //发放奖励
            tradeWarModule.sendReward(battleResult, false);
            //增加记录
            tradeWarModule.addRecord(battleResult);
            AutoLogMgr.add(new LogTradeWarBattle(player.getUserId(), battleResult.getBattleType(), battleResult.getEnemyUserId(),
                    StringUtils.listToString(battleResult.getMyPatronsIdList(), ","),
                    battleResult.getKillPatronsCount() * battleResult.getWarTimes(), battleResult.getReward(), oldScore,
                    battleResult.getMyAddScore(), userTradeWarInfo.getScore(), battleResult.getEnemyLoseScore(), 0));
            //商战次数任务、成就
            tradeWarModule.notifyTradeWarTimes(battleResult.getWarTimes());

            log.info("trade war fast battle cost:{},battleTimes:{},teamIndex:{}", System.currentTimeMillis() - preTime, battleResult.getWarTimes(), data.getTeamIndex());
            resultList.add(battleResult);
        }
        log.info("trade war fast battle total cost:{}", System.currentTimeMillis() - totalPreTime);
        return resultList;
    }

    /**
     * 获取队伍总门客数量
     * @return
     */
    public int getTeamPatronsCount(){
        int patronsCount = 0;
        for(List<Integer> dataList : userTradeWarTeam.getPatronsTeamList()){
            patronsCount += dataList.size();
        }
        return patronsCount;
    }

    /**
     * 获取队伍数量
     *
     * @return
     */
    public int getTeamCount() {
        return userTradeWarTeam.getPatronsTeamList().size();
    }

    public int getCrossTeamCount() {
        return userCrossTradeWarTeam.getPatronsTeamList().size();
    }

    /**
     * 检测门客重复
     *
     * @param patronsIdList
     * @return
     */
    public boolean checkPatronsRepeat(int index, List<Integer> patronsIdList, int teamType) {
        if (teamType == 0) {
            for (int patronsId : patronsIdList) {
                int i = 0;
                for (List<Integer> dataList : userTradeWarTeam.getPatronsTeamList()) {
                    if (i != index) {
                        if (dataList.contains(patronsId)) {
                            return true;
                        }
                    }
                    i++;
                }
            }
        } else {
            for (int patronsId : patronsIdList) {
                int i = 0;
                for (List<Integer> dataList : userCrossTradeWarTeam.getPatronsTeamList()) {
                    if (i != index) {
                        if (dataList.contains(patronsId)) {
                            return true;
                        }
                    }
                    i++;
                }
            }
        }

        return false;
    }

    public UserTradeWarTeam getUserTradeWarTeam() {
        return userTradeWarTeam;
    }

    public UserCrossTradeWarTeam getUserCrossTradeWarTeam() {
        return userCrossTradeWarTeam;
    }

    public String getTeamData(int teamType) {
        if (teamType == 0) {
            if (userTradeWarTeam == null) {
                return "";
            }
            return userTradeWarTeam.getPatronsTeamListString();
        } else {
            if (userCrossTradeWarTeam == null) {
                return "";
            }
            return userCrossTradeWarTeam.getPatronsTeamListString();
        }
    }

    public String getTeamBuyBuffData(int teamType){
        if (teamType == 0) {
            if (userTradeWarTeam == null) {
                return "";
            }
            return userTradeWarTeam.getBuyBuffTimesListString();
        } else {
            if (userCrossTradeWarTeam == null) {
                return "";
            }
            return userCrossTradeWarTeam.getBuyBuffTimesListString();
        }
    }

    /**
     * 队伍鼓舞次数
     *
     * @param defineBuyBuffTimes
     * @param battleTimes
     * @return
     */
    private int teamBuyBuffTimes(int defineBuyBuffTimes, int battleTimes) {
        int buyBuffTimes = 0;
        if (defineBuyBuffTimes > GameConfig.TRADE_WAR_BUFF_MAX_TIMES) {
            defineBuyBuffTimes = GameConfig.TRADE_WAR_BUFF_MAX_TIMES;
        }
        UserTradeWarInfo userTradeWarInfo = player.getModule(TradeWarModule.class).getUserTradeWarInfo();
        for (int i = 0; i < defineBuyBuffTimes; i++) {
            BigInteger cost = TradeWarConfigMgr.getTradeWarBuffCost(player.getUserInfo().getEarnSpeed(), buyBuffTimes + 1);
            if (cost.compareTo(BigInteger.ZERO) > 0) {
                if (battleTimes > 1) {
                    cost = cost.multiply(BigInteger.valueOf(battleTimes));
                }
                if (player.getModule(CurrencyModule.class).removeCurrency(new Property(GameConfig.GAME_MONEY_SILVER, cost),
                        eLogMoneyType.TradeWar, eLogMoneyType.TradeWarBuyBuff)) {
                    buyBuffTimes++;
                    if(null != userTradeWarInfo) {
                        userTradeWarInfo.setTotalBuyBuffTimes(userTradeWarInfo.getTotalBuyBuffTimes() + battleTimes);
                    }
                } else {
                    break;
                }
            }else {
                break;
            }
            if(buyBuffTimes >= GameConfig.TRADE_WAR_BUFF_MAX_TIMES){
                break;
            }
        }
        return buyBuffTimes;
    }

    public int calcCrossTradeWarBuffTimes(int teamNum){
        //计算鼓舞
        int defineBuyBuffTimes = TradeWarConfigMgr.getTeamBuyBuffTimes(userCrossTradeWarTeam.getBuyBuffTimes(teamNum - 1));
        int buyBuffTimes = teamBuyBuffTimes(defineBuyBuffTimes, 1);
        return buyBuffTimes;
    }

    /**
     * 设置队伍鼓舞
     *
     * @param index
     * @param teamType
     * @return
     */
    public int setTradeWarTeamBuyBuff(int index, int type, int teamType){
        int result = titleOrVipCheck(teamType);
        if(0 != result){
            return result;
        }
        if (teamType==0){
            if(null == userTradeWarTeam){//系统未解锁
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
            int teamSize = userTradeWarTeam.getPatronsTeamList().size();
            if(index < 0 || index > teamSize){
                return GameErrorCode.E_TRADE_WAR_TEAM_NO_EXIST;
            }
            userTradeWarTeam.setBuyBuffTimes(index, type, teamSize);
        }else{
            if(null == userCrossTradeWarTeam){//系统未解锁
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
            int teamSize = userCrossTradeWarTeam.getPatronsTeamList().size();
            if(index < 0 || index > teamSize){
                return GameErrorCode.E_TRADE_WAR_TEAM_NO_EXIST;
            }
            userCrossTradeWarTeam.setBuyBuffTimes(index, type, teamSize);
        }

        return 0;
    }

    /**
     * 给快速出战队伍排序
     * @param teamList
     * @return
     */
    private LinkedList<TradeWarTeamSortEntity> getSortTeamList(List<List<Integer>> teamList){
        LinkedList<TradeWarTeamSortEntity> sortList = new LinkedList<>();
        if(null != teamList){
            for(int i = 0; i < teamList.size(); i++){
                TradeWarTeamSortEntity data = new TradeWarTeamSortEntity();
                data.setTeamIndex(i);
                data.setPatronsIdList(teamList.get(i));
                sortList.addLast(data);
            }
        }
        sortList.sort((o1, o2) -> {
            PatronsModule patronsModule = player.getModule(PatronsModule.class);
            List<UserPatrons> patronsList1 = patronsModule.getUserPatronsList(o1.getPatronsIdList());
            List<UserPatrons> patronsList2 = patronsModule.getUserPatronsList(o2.getPatronsIdList());
            BigInteger ability1 = BattleManager.getPatronsListAbility(patronsList1);
            BigInteger ability2 = BattleManager.getPatronsListAbility(patronsList2);
            return ability2.compareTo(ability1);
        });
        return sortList;
    }
}
